package GetHtml;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class GetHtml {
	private static SSLContext ssl = null;
	private static int trytime = 3;
	private static HashMap<String, String> requestpropertys = new HashMap<String, String>();
	
	static 
	{
		//设置ssl证书，自动忽略https的证书验证
		try {
			TrustManager[] trustallcert = {new X509TrustManager()
			{
				@Override
				public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
				}
	
				@Override
				public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
				}
	
				@Override
				public X509Certificate[] getAcceptedIssuers() {
					return null;
				}
			}};
			ssl = SSLContext.getInstance("SSL");
			ssl.init(null, trustallcert, new SecureRandom());
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
	}
	
	public static void setRequestProperty(String key, String value) {
		requestpropertys.put(key, value);
		return;
	}
	
	public static void setTryTime(int times)
	{
		trytime = times;
		return;
	}
	
	//根据网址和编码集获取网页内容，get方式获取
	public static String getHtmlInfo(String Urladdress, String charset)
	{
		if(Urladdress == null || charset == null) return null;
		URL url;
		StringBuffer result = new StringBuffer();
		BufferedReader br = null;
		HttpURLConnection con = null;

		while(trytime > 0)
		{
			try {
				url = new URL(Urladdress);
				con = (HttpURLConnection)url.openConnection();
				//增加https证书认证
				if(Urladdress.startsWith("https"))
				{
					((HttpsURLConnection)con).setSSLSocketFactory(ssl.getSocketFactory());
				}
				HttpURLConnection.setFollowRedirects(true);
				con.setRequestProperty("Connection", "keep-alive");
				con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36");
				con.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
				con.setRequestMethod("GET");
				for (String requestkey : requestpropertys.keySet()) {
					con.setRequestProperty(requestkey, requestpropertys.get(requestkey));
				}
				con.setConnectTimeout(10 * 1000);
				con.setReadTimeout(10 * 1000);
				br = new BufferedReader(new InputStreamReader(con.getInputStream(), charset));
				String line = null;
				while((line = br.readLine()) != null)
				{
					result.append(line+"\r\n");
				}
				return result.toString();
			} catch (Exception e) {
				System.out.println(Urladdress + "连接超时，重试" + trytime);
				trytime--;			
			}
			finally
			{
				
				try {
					if (br != null) br.close();
					requestpropertys.clear();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
	
	//根据网址和编码集获取网页内容，post方式获取
	public static String postHtmlInfo(String Urladdress, String inputString, String inputcharset, String outputcharset)
	{
		if(Urladdress == null || inputcharset == null || outputcharset == null) return null;
		URL url;
		StringBuffer result = new StringBuffer();
		OutputStream os = null;
		BufferedReader br = null;
		
		while(trytime > 0)
		{
			try {
				url = new URL(Urladdress);
				HttpURLConnection con = (HttpURLConnection)url.openConnection();
				//增加https证书认证
				if(Urladdress.startsWith("https"))
				{
					((HttpsURLConnection)con).setSSLSocketFactory(ssl.getSocketFactory());
				}
				HttpURLConnection.setFollowRedirects(true);
				con.setDoOutput(true); //设置打开输入流，这是post必须要使用的
				con.setDoInput(true);
				con.setRequestMethod("POST");
				con.setRequestProperty("Connection", "keep-alive");
				con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36");
				con.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
				for (String requestkey : requestpropertys.keySet()) {
					con.setRequestProperty(requestkey, requestpropertys.get(requestkey));
				}
				con.setConnectTimeout(10 * 1000);
				con.setReadTimeout(10 * 1000);
				os = con.getOutputStream();
				
				//填入需要post的表单数据
				os.write(inputString.getBytes(outputcharset));
				os.flush();
				
				//获取返回的网页信息
				br = new BufferedReader(new InputStreamReader(con.getInputStream(), inputcharset));
				String line = null;
				while((line = br.readLine()) != null)
				{
					result.append(line+"\r\n");
				}
				return result.toString();
			} catch (Exception e) {
				System.out.println(Urladdress + "连接超时，重试" + trytime);
				trytime--;			
			}
			finally
			{				
				try {
					if(os != null) os.close();
					if(br != null) br.close();
					requestpropertys.clear();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}		
		return null;
	}
	
	// 通过seleniumz抓取网页内容，仅限Chrome
	public static String getHtmlInfoByseleniumz(String url, String chromedrivepath) {
		// 先检测文件是否符合要求
		if (!chromedrivepath.contains("chromedriver.exe")) {
			System.out.println("is not a chromedriver");
			return null;
		}
		
		File file = new File(chromedrivepath);
		if (!file.exists()) {
			System.out.println(chromedrivepath + " not exist");
			return null;
		}
		
		try {
			ChromeOptions options = new ChromeOptions();
			options.addArguments("--headless");
			options.addArguments("--disable-gpu");
			System.setProperty("webdriver.chrome.driver", chromedrivepath);
	        WebDriver driver = new ChromeDriver(options);
	        driver.get(url);
	        String result = driver.getPageSource();
	        driver.close();
	        
	        return result;	
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	// 发送Options
	public static HttpURLConnection optionsHtmlInfo(String Urladdress, String charset)
	{
		if(Urladdress == null || charset == null) return null;
		URL url;
		HttpURLConnection con = null;

		while(trytime > 0)
		{
			try {
				url = new URL(Urladdress);
				con = (HttpURLConnection)url.openConnection();
				//增加https证书认证
				if(Urladdress.startsWith("https"))
				{
					((HttpsURLConnection)con).setSSLSocketFactory(ssl.getSocketFactory());
				}
				HttpURLConnection.setFollowRedirects(true);
				con.setRequestProperty("Connection", "keep-alive");
				con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36");
				con.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
				con.setRequestMethod("OPTIONS");
				for (String requestkey : requestpropertys.keySet()) {
					con.setRequestProperty(requestkey, requestpropertys.get(requestkey));
				}
				con.setConnectTimeout(10 * 1000);
				con.setReadTimeout(10 * 1000);
				return con;

			} catch (Exception e) {
				System.out.println(Urladdress + "连接超时，重试" + trytime);
				trytime--;			
			}
			finally
			{
				requestpropertys.clear();
			}
		}
		return null;
	}
}
